package com.prs.crm.dao.project.impl;

import java.util.Collection;
import java.util.List;

import org.courser.Util;
import org.hibernate.Criteria;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.hibernate3.HibernateCallback;

import com.prs.crm.context.Constrains;
import com.prs.crm.context.ToolKits;
import com.prs.crm.dao.impl.BaseDaoImpl;
import com.prs.crm.dao.project.TaskDao;
import com.prs.crm.domain.hr.Person;
import com.prs.crm.domain.project.Project;
import com.prs.crm.domain.project.Task;
import com.prs.crm.domain.project.TaskAttach;
import com.prs.crm.domain.project.TaskCritique;

public class TaskDaoImpl extends BaseDaoImpl<Task> implements TaskDao {
	
	public void saveTaskAttach(TaskAttach attach)
	{
		this.getHibernateTemplate().save(attach);
	}
	
	public int batchRemoveAttachs(final Integer[] attachIds)
	{
		 return (Integer)this.getHibernateTemplate().execute(
					new HibernateCallback()
					{
						public Object doInHibernate(Session session) throws HibernateException {
							String idstr = ToolKits.constructInSql(attachIds);
				        	Query query = session.createQuery("delete from TaskAttach where id in ("+idstr+")");
				        	return  query.executeUpdate();
				        	
				        }   
					}
			);
	}
	
	@SuppressWarnings("unchecked")
	public Collection<Task> findExecuteTask(final Person person,final int result)
	{
		 return (Collection<Task>)this.getHibernateTemplate().execute(
					new HibernateCallback()
					{
						public Object doInHibernate(Session session) throws HibernateException {
				        	Criteria criteria = session.createCriteria(Task.class);
				        	criteria.add(Restrictions.eq("executor", person))
				        				.addOrder(Order.asc("id"));
				        	return  criteria.setMaxResults(result).list();
				        	
				        }   
					}
			);
	}
	
	public void saveCritique(TaskCritique critique)
	{
		this.getHibernateTemplate().save(critique);
	}
	
	public Task findRootTask(final Project project)
	{
		 return (Task)this.getHibernateTemplate().execute(
					new HibernateCallback()
					{
						@SuppressWarnings("unchecked")
						public Object doInHibernate(Session session) throws HibernateException {
				        	Criteria criteria = session.createCriteria(Task.class);
				        	criteria.add(Restrictions.eq("project", project))
				        				.add(Restrictions.isNull("parent"));
				        	List result = criteria.list();
				        	if (result.size()>0)
				        		return result.get(0);
				        	else
				        		return null;
				        }   
					}
			);
	}
	
	@SuppressWarnings("unchecked")
	public Collection<Task> findRootTasks(final Integer[] projectIds)
	{
		 return (Collection<Task>)this.getHibernateTemplate().execute(
					new HibernateCallback()
					{
						public Object doInHibernate(Session session) throws HibernateException {
				        	Criteria criteria = session.createCriteria(Task.class);
				        	criteria.add(Restrictions.in("project.id", projectIds))
				        				.add(Restrictions.isNull("parent"))
				        				.addOrder(Order.asc("id"));
				        	return  criteria.list();
				        	
				        }   
					}
			);
	}
	
	
	public int updateProjectTaskStatus(final Project project,final  Integer status,final Integer flowstatus)
	{
		 return (Integer)this.getHibernateTemplate().execute(
					new HibernateCallback()
					{
						public Object doInHibernate(Session session) throws HibernateException {
				        	String hql="update Task t  set status=?,flowstatus=? where t.project=?";
				        	Query query = session.createQuery(hql);
				        	query.setParameter(0, status).setParameter(1, flowstatus)
				        		.setParameter(2, project);
				        	return query.executeUpdate();
				        }   
					}
			);
	}
	
	public 	int updateProjectTaskStatus(final Project project,final Integer status)
	{
		 return (Integer)this.getHibernateTemplate().execute(
					new HibernateCallback()
					{
						public Object doInHibernate(Session session) throws HibernateException {
				        	String hql="update Task t  set status=? where t.project=?";
				        	Query query = session.createQuery(hql)
				        		.setParameter(0, status)
				        		.setParameter(1, project);
				        	return query.executeUpdate();
				        }   
					}
			);
	}
	
	
	public int countExecuteTask(final Person executor)
	{
		 return (Integer)this.getHibernateTemplate().execute(
					new HibernateCallback()
					{
						public Object doInHibernate(Session session) throws HibernateException {
							Criteria criteria = session.createCriteria(Task.class);
							criteria.add(Restrictions.eq("executor",executor))
										.add(Restrictions.eq("status", Constrains.TASK_STATUS_PROCESS));
							criteria.setProjection(Projections.rowCount());
							return criteria.uniqueResult();
				        }   
					}
			);
	}
	

	public int countJoinTask(final Person joiner)
	{
		 return (Integer)this.getHibernateTemplate().execute(
					new HibernateCallback()
					{
						public Object doInHibernate(Session session) throws HibernateException {
							Criteria criteria = session.createCriteria(Task.class);
							criteria.createAlias("joiner", "j")
										.add(Restrictions.eq("j.id", joiner.getId()));
							criteria.setProjection(Projections.rowCount());
							return criteria.uniqueResult();
				        }   
					}
			);
	}
	
	

	public int countVerifyTask(final Person verifyer)
	{
		 return (Integer)this.getHibernateTemplate().execute(
					new HibernateCallback()
					{
						public Object doInHibernate(Session session) throws HibernateException {
							Criteria criteria = session.createCriteria(Task.class);
							criteria.add(Restrictions.eq("verifer", verifyer))
								.add(Restrictions.eq("flowstatus", Constrains.WORKFLOWPROCESS_STATE_PROCESS));
							criteria.setProjection(Projections.rowCount());
							return criteria.uniqueResult();
				        }   
					}
			);
	}
	

	public int countSumitReportTask(final Person executor)
	{
		 return (Integer)this.getHibernateTemplate().execute(
					new HibernateCallback()
					{
						public Object doInHibernate(Session session) throws HibernateException {
							try
							{
								Criteria criteria = session.createCriteria(Task.class);
								criteria.add(Restrictions.eq("executor",executor))
									.add(Restrictions.eq("status", Constrains.TASK_STATUS_PROCESS));
								criteria.add(Restrictions.ge("nearSubmitTime", 
											Util.addTimeByDay(Util.nowFullTime(), -1)));
								criteria.setProjection(Projections.rowCount());
								return criteria.uniqueResult();
							}
							catch (Exception e)
							{
								e.printStackTrace();
								return 0;
							}
				        }   
					}
			);
	}
	
	public int countInValidTask(final Person executor)
	{
		 return (Integer)this.getHibernateTemplate().execute(
					new HibernateCallback()
					{
						public Object doInHibernate(Session session) throws HibernateException {
							try
							{
								Criteria criteria = session.createCriteria(Task.class);
								criteria.add(Restrictions.eq("executor", executor))
								.add(Restrictions.eq("flowstatus", Constrains.WORKFLOWENTITY_STATE_INVALID));
								criteria.setProjection(Projections.rowCount());
								return criteria.uniqueResult();
							}
							catch (Exception e)
							{
								e.printStackTrace();
								return 0;
							}
				        }   
					}
			);
	}
	
}
